home *** CD-ROM | disk | FTP | other *** search
/ MacPeople 2003 February 1 / MACPEOPLE-2003-02-01.ISO.7z / MACPEOPLE-2003-02-01.ISO / ぶらりオンラインウェアの旅 / おしゃべり漂流記 / xGates / xGates 1.2 Source Code.sit / xGates 1.2 Source Code / game.c < prev    next >
Text File  |  2002-12-08  |  48KB  |  1,966 lines

  1. /*
  2.     xGates -- Stunningly entertaining action game for MacOS Classic / MacOS X
  3.     Copyright (C) 2002 Sveinbjorn Thordarson <paladeen@soth.zoneit.com>
  4.  
  5.     This program is free software; you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation; either version 2 of the License, or
  8.     (at your option) any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program; if not, write to the Free Software
  17.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  
  19.     game.c
  20.  
  21. */
  22.  
  23.  
  24. #include "externs.h"
  25. #include "prototypes.h"
  26. #include "definitions.h"
  27.  
  28. #include <math.h>
  29.  
  30.  
  31. long    framerate;
  32. short   counter;
  33.  
  34.  
  35.  
  36. void DoGameFrame (void)
  37. {
  38.     UnsignedWide    start, end;
  39.     long            elapsed;
  40.     long            tempTickCount = 0;
  41.     short           counter = 0;
  42.     Boolean         busy = true;
  43.  
  44.         //if we have a fixed framerate, we need to get ticks
  45.         if (prefs.fixedFrameRate)
  46.                 tempTickCount = TickCount();
  47.                 
  48.         //start timing framedraw for DrawFPS
  49.         if (prefs.drawFPS)
  50.               Microseconds(&start);
  51.  
  52.         
  53.         
  54.         
  55.         
  56.         
  57.         //if level's finished
  58.         if (levelCompleted == 1)
  59.         {
  60.             if (CheckIfAllMacsHaveBecomeCorrupted())
  61.             {
  62.                 GameOver();
  63.             }
  64.             else
  65.             {
  66.                 Sleep(10);
  67.                 EndLevel();
  68.             }
  69.         }
  70.         else if (levelCompleted > 1)
  71.             levelCompleted--;
  72.         
  73.         //if there's less than the maximum of bills and DoJ not in effect, we add ones
  74.         if (numOfBills != levels[currentLevel].maxBills &&  dojCooldown == 0)
  75.         {
  76.             AddBill();
  77.         }
  78.         
  79.         //if there are no bills, we shut off bill sounds
  80.         if (numOfBills == 0)
  81.         {
  82.             SilenceChannel(dojSndChannel);
  83.             AddBill();
  84.         }
  85.         
  86.         //see if player gets a goodie
  87.         RandomGoodie(kGoodieChance+RandomBetween(0, 1));
  88.         
  89.         if (dojCooldown)
  90.             dojCooldown--;
  91.         
  92.         
  93.         
  94.         //draw the entire game stuff to offscreen gworld
  95.         DrawGameBoard();
  96.         
  97.         if (prefs.drawFPS)
  98.             DrawFrameRateToWorkMap(framerate);
  99.  
  100.         DSpContext_SwapBuffers(gDisplayContext, nil, nil);
  101.  
  102.         ServiceMusic();
  103.         
  104.         CheckForMouse();
  105.         
  106.         DoExtraMoves();//poofs and dojs
  107.         CheckKeysInGame();
  108.         
  109.         DoSteveMove();
  110.         DoBillMoves();
  111.         
  112.         
  113.         //if we have a fixed framerate, we wait for a while at the end of each frame
  114.         if (prefs.fixedFrameRate)
  115.         {
  116.             do
  117.             {
  118.                   //WaitNextEvent(mouseDown, &theEvent, 0, nil);
  119.                 //HandleEvent(&theEvent);
  120.             }
  121.             while(tempTickCount + 1 >= TickCount());
  122.         }
  123.         
  124.         if (prefs.drawFPS)
  125.         {
  126.             Microseconds(&end);
  127.             //the time for one frame to finish, including everything
  128.             elapsed = end.lo - start.lo;
  129.             //calculate how many a second that adds up to
  130.             framerate = 1000000/elapsed;
  131.         }
  132. }
  133.  
  134.  
  135.  
  136.  
  137.  
  138. #pragma mark -
  139.  
  140.  
  141. //////////////////////////////////////////////////////
  142. //Initiate all the variables used during game play
  143. //////////////////////////////////////////////////////
  144.  
  145. void NewGame (void)
  146. {
  147.     short           rand = RandomBetween(1, 100);//init random num
  148.  
  149.     HideCursor();
  150.  
  151.     ResetMacsInAllLevels();
  152.     SilenceAllChannels();
  153.  
  154.     gWhere = kPlayingGame;
  155.     cheated = false;
  156.     currentLevel = 0;
  157.     currentBillSpeed = kBillStartSpeed;
  158.     
  159.  
  160.     
  161.     
  162.     lastBillStartLoc = -1;
  163.     
  164.     numOfBills = 0;
  165.     numOfSteves = 0;
  166.     numOfDojs = 0;
  167.     numOfPoofs = 0;
  168.     
  169.     billsInLevel = 0;
  170.     
  171.     player.score = 0;
  172.     player.dojs = 0;
  173.     player.totalBillsKilled = 0;
  174.     
  175.     levelCompleted = 0;
  176.     gNumUpdateRects = 0;
  177.     
  178.     
  179.     gPlaying = true;
  180.       StartLevel(0);
  181.  
  182. }
  183.  
  184.  
  185. //////////////////////////////////////////////////////
  186. //Check highscore place and return to non-playing state
  187. //////////////////////////////////////////////////////
  188.  
  189. void GameOver (void)
  190. {
  191.     short place = 0;
  192.  
  193.     if (!gPlaying)
  194.     {
  195.         return;
  196.     }
  197.     
  198.     SilenceAllChannels();
  199.     
  200.     if (prefs.sound)
  201.     {
  202.         SndPlay(otherSndChannel, (SndListHandle)gameOverSnd, true);
  203.         Sleep(313);
  204.     }
  205.     
  206.     gPlaying = false;
  207.     
  208.     ShowCursor();
  209.     
  210.     player.place = CheckPlaceInHighscoreList();
  211.     
  212.     //player made it on high score list
  213.     if (player.place < 16)
  214.     {
  215.         if (prefs.sound)
  216.         {
  217.             SilenceAllChannels();
  218.             SndPlay(otherSndChannel, (SndListHandle)yeahSnd, true);
  219.         }
  220.         DoGetPlayerName();
  221.     }
  222.     else
  223.     {
  224.         EndGame();
  225.     }
  226.     
  227.     
  228. }
  229.  
  230.  
  231. //////////////////////////////////////////////////////
  232. //Return to splash screen
  233. //////////////////////////////////////////////////////
  234.  
  235. void EndGame (void)
  236. {
  237.     if (IsMenuBarVisible())
  238.     {
  239.         HideMenuBar();
  240.     }
  241.     DoSplashScreen();
  242. }
  243.  
  244.  
  245. //////////////////////////////////////////////////////
  246. //Zoom to the win screen, wait a while and then check
  247. //for place in highscore chart before returning to splash
  248. //////////////////////////////////////////////////////
  249.  
  250. void GameWon (void)
  251. {    
  252.     SilenceAllChannels();
  253.  
  254.     ShowCursor();
  255.  
  256.     gPlaying = false;
  257.     
  258.     gWhere = kGameWon;
  259.     
  260.     
  261.     
  262.     DrawGameWonScreen();
  263.     
  264.     
  265.     //play zoom sound
  266.     
  267.     if (prefs.sound)
  268.     {
  269.         SndPlay(otherSndChannel, (SndListHandle)zoomSnd, true);
  270.     }
  271.             
  272.     ZoomBlitWorkMapToScreen();
  273.  
  274.     if (prefs.sound)
  275.     {
  276.         SndPlay(billSndChannel, (SndListHandle)yeahSnd, true);
  277.     }
  278.     
  279.     
  280.  
  281. }
  282.  
  283. #pragma mark -
  284.  
  285.  
  286. //////////////////////////////////////////////////////
  287. //Set up high score prompt, await input
  288. //////////////////////////////////////////////////////
  289.  
  290. void DoGetPlayerName (void)
  291. {
  292.     CGrafPtr    frontBuffPort;
  293.  
  294.     DSpContext_GetFrontBuffer(gDisplayContext, &frontBuffPort);
  295.  
  296.     gWhere = kHighScore;
  297.     
  298.     
  299.     DrawHighScorePrompt();
  300.     
  301.     ZoomBlitWorkMapToScreen();
  302.     
  303.     SetPort(frontBuffPort);
  304.     playerNameTextField = TENew(&textFieldRect, &textFieldRect);
  305.     TESetAlignment( teFlushLeft, playerNameTextField);
  306.     TEActivate(playerNameTextField);
  307.  
  308.     TESetSelect(0, 4, playerNameTextField);
  309.  
  310. }
  311.  
  312.  
  313. //////////////////////////////////////////////////////
  314. //Loop through highscores to find player's place
  315. //////////////////////////////////////////////////////
  316. short CheckPlaceInHighscoreList (void)
  317. {
  318.     short i;
  319.     
  320.     //if player has cheated, has changed framerate or disabled chainsaw jamming, he can't get on the highscore chart, the devil!
  321.     if (cheated == true || prefs.noChainsawJamming == true)
  322.         return(10000);
  323.     
  324.     for (i = 0; i < 16; i++)
  325.     {
  326.         if (player.score > prefs.highscores.score[i])
  327.         {
  328.                return(i);
  329.         }
  330.     }
  331.  
  332.     return(i);
  333.  
  334. }
  335.  
  336. //////////////////////////////////////////////////////
  337. //Load player name from textfield and score into
  338. //the highscore structure
  339. //////////////////////////////////////////////////////
  340.  
  341. void AddScoreToHighScoreChart (void)
  342. {
  343.     short i;
  344.     Str255      someStr = "¥p";
  345.     Str255      nameStr = "¥p";
  346.     
  347.     //create handle to memory to store name
  348.     CharsHandle theCharHandle = NewHandle(15);
  349.  
  350.     //load name from text field into handle
  351.     theCharHandle = TEGetText(playerNameTextField);
  352.   
  353.     //copy it into Pascal string
  354.     c2pstrcpy(nameStr,*theCharHandle);
  355.     
  356.     //dispose of handle
  357.     DisposeHandle(theCharHandle);
  358.     
  359.     //prevent
  360.     nameStr[0] = (*playerNameTextField)->teLength;
  361.  
  362.     for (i = 15; i >= player.place+1; i--)
  363.     {
  364.         prefs.highscores.score[i] = prefs.highscores.score[i-1];
  365.         pStrcpy(prefs.highscores.name[i], prefs.highscores.name[i-1]);
  366.     }
  367.  
  368.     pStrcpy(prefs.highscores.name[player.place], nameStr);
  369.     prefs.highscores.score[player.place] = player.score;
  370.     
  371.     prefs.lastHighScore = player.place;
  372.     
  373. }
  374.  
  375.  
  376.  
  377. #pragma mark -
  378.  
  379.  
  380. //////////////////////////////////////////////////////
  381. //Increment level count, increase speed and init
  382. //level-specific variables
  383. //////////////////////////////////////////////////////
  384. void UpOneLevel (void)
  385. {
  386.     
  387.  
  388.     currentLevel++;
  389.     
  390.     //increment bill speed as dictated by level
  391.     currentBillSpeed += levels[currentLevel].billSpeed;
  392.     
  393.     lastBillStartLoc = -1;
  394.     
  395.     //all game objects set to 0
  396.     numOfBills = 0;
  397.     numOfSteves = 0;
  398.     numOfDojs = 0;
  399.     numOfPoofs = 0;
  400.  
  401.     billsInLevel = 0;
  402.     
  403.     levelCompleted = 0;
  404.     levelScore = 0;
  405.     
  406. }
  407. //////////////////////////////////////////////////////
  408. //Do the pre-level lockup thing listing bills and macs
  409. //before zooming to an active game screen
  410. //////////////////////////////////////////////////////
  411.  
  412. void StartLevel (short levelNum)
  413. {
  414.     short       i;
  415.     Rect        iconRect;
  416.     Str255      levelNumString;
  417.     Rect        bigChainsawRect = { 26, 170, 200, 470 };
  418.     CGrafPtr    frontBuffPort, backBuffPort;
  419.     
  420.     DSpContext_GetFrontBuffer(gDisplayContext, &frontBuffPort);
  421.     DSpContext_GetBackBuffer (gDisplayContext, kDSpBufferKind_Normal, &backBuffPort);
  422.     
  423.     SilenceAllChannels();
  424.     
  425.     //the levelNum is for adding a cheat
  426.     currentLevel = levelNum;
  427.     
  428.     
  429.     NumToString(levelNum+1, levelNumString);
  430.     
  431.     gWhere = kStartLevel;
  432.        
  433.     SetPort(backBuffPort);
  434.     //draw a black background on the workmap
  435.     DrawBlackWorkMap();
  436.     //draw big chainsaw
  437.     CopyBits((BitMap *)*chainSawBigPix, GetPortBitMapForCopyBits(backBuffPort), &chainsawBigSize, &bigChainsawRect, srcCopy, nil);
  438.     
  439.     if (prefs.sound)
  440.     {
  441.         //play zoom sound
  442.         SndPlay(otherSndChannel, (SndListHandle)zoomSnd, true);
  443.     }
  444.     
  445.      ZoomBlitWorkMapToScreen();
  446.  
  447.  
  448.  
  449.     //draw the Start Level screen
  450.     SetPort(frontBuffPort);
  451.     
  452.     
  453.             
  454.             RGBForeColor(&myWhiteColor);
  455.             
  456.             //Draw "Proceeding to level X
  457.             MoveTo(250,225);
  458.             TextSize(12);
  459.             TextFace(1);
  460.             DrawString("¥pProceeding to Level ");
  461.             DrawString(levelNumString);
  462.             RGBForeColor(&myBlackColor);
  463.             
  464.             if (prefs.sound)
  465.             {
  466.                 SilenceChannel(weaponSndChannel);
  467.                 SndPlay(weaponSndChannel, (SndListHandle)bonkSnd, true);
  468.             }
  469.             
  470.             Sleep(20);
  471.             
  472.             //Draw dots
  473.             RGBForeColor(&myWhiteColor);
  474.             DrawString("¥p .");
  475.             
  476.             if (prefs.sound)
  477.             {
  478.                 SilenceChannel(weaponSndChannel);
  479.                 SndPlay(weaponSndChannel, (SndListHandle)bonkSnd, true);
  480.             }
  481.             
  482.             RGBForeColor(&myBlackColor);
  483.             Sleep(5);
  484.             
  485.             RGBForeColor(&myWhiteColor);
  486.             DrawString("¥p .");
  487.             
  488.             if (prefs.sound)
  489.             {
  490.                 SilenceChannel(weaponSndChannel);
  491.                 SndPlay(weaponSndChannel, (SndListHandle)bonkSnd, true);
  492.             }
  493.             
  494.             RGBForeColor(&myBlackColor);
  495.             Sleep(5);
  496.             
  497.             RGBForeColor(&myWhiteColor);
  498.             DrawString("¥p .");
  499.             
  500.             if (prefs.sound)
  501.             {
  502.                 SilenceChannel(weaponSndChannel);
  503.                 SndPlay(weaponSndChannel, (SndListHandle)bonkSnd, true);
  504.             }
  505.             RGBForeColor(&myBlackColor);
  506.        
  507.             Sleep(35);
  508.             
  509.             //Draw No. of Macs text
  510.             RGBForeColor(&myWhiteColor);
  511.             TextSize(10);
  512.             TextFace(1);
  513.             MoveTo(185,270);
  514.             DrawString("¥pNo. of Macs: ");
  515.             TextFace(0);
  516.             RGBForeColor(&myBlackColor);
  517.  
  518.             if (prefs.sound)
  519.             {
  520.                 SndPlay(weaponSndChannel, (SndListHandle)bonkSnd, true);
  521.             }
  522.             Sleep(15);
  523.             
  524.     //draw macs appearing
  525.     RGBForeColor(&myBlackColor);
  526.     for (i = 0; i < levels[levelNum].numOfMacs; i++)
  527.     {
  528.         iconRect.top = 250;
  529.         iconRect.left = 280 + (i * macIconSizes[0].right);
  530.         iconRect.bottom = iconRect.top + macIconSizes[0].bottom;
  531.         iconRect.right = iconRect.left + macIconSizes[0].right;
  532.         
  533.         CopyBits((BitMap *)*macIconPix, GetPortBitMapForCopyBits(frontBuffPort), &macIconSizes[0], &iconRect, srcCopy, nil);
  534.         
  535.         if (prefs.sound)
  536.         {
  537.             SilenceChannel(weaponSndChannel);
  538.             SndPlay(weaponSndChannel, (SndListHandle)bonkSnd/*macStartupSnd*/, true);
  539.         }
  540.         
  541.         Sleep(5);
  542.     }
  543.     
  544.  
  545.     Sleep(35);
  546.  
  547.     
  548.     //draw Max no. of Bills text
  549.        RGBForeColor(&myWhiteColor);
  550.        MoveTo(159,330);
  551.        TextSize(10);
  552.        TextFace(1);
  553.        DrawString("¥p    Max No. of Bills:");
  554.        RGBForeColor(&myBlackColor);
  555.  
  556.        if (prefs.sound)
  557.        {
  558.             SndPlay(weaponSndChannel, (SndListHandle)bonkSnd, true);
  559.         }
  560.     
  561.     RGBForeColor(&myBlackColor);
  562.     
  563.     Sleep(15);
  564.     
  565.     //draw bills appearing
  566.     for (i = 0; i < levels[levelNum].maxBills; i++)
  567.     {
  568.         iconRect.top = 300;
  569.         iconRect.left = 280 + (i * billIconSize.right);
  570.         iconRect.bottom = iconRect.top + billIconSize.bottom;
  571.         iconRect.right = iconRect.left + billIconSize.right;
  572.         
  573.         CopyBits((BitMap *)*billIconPix, GetPortBitMapForCopyBits(frontBuffPort), &billIconSize, &iconRect, srcCopy, nil);
  574.         
  575.         if (prefs.sound)
  576.         {
  577.             SilenceChannel(weaponSndChannel);
  578.             SndPlay(weaponSndChannel, (SndListHandle)billScreamSnd, true);
  579.         }
  580.         
  581.         Sleep(5);
  582.     }
  583.  
  584.     
  585.     Sleep(35);
  586.     
  587.  
  588.        RGBForeColor(&myWhiteColor);
  589.        MoveTo(240,400);
  590.        TextSize(12);
  591.        TextFace(1);
  592.        DrawString("¥pGet Ready to Kill Some Bill!");
  593.        RGBForeColor(&myBlackColor);
  594.  
  595.         if (prefs.sound)
  596.         {
  597.             SndPlay(weaponSndChannel, (SndListHandle)bonkSnd, true);
  598.         }
  599.  
  600.     
  601.     //Get Ready To Kill Some Bill
  602.         if (prefs.sound)
  603.         {
  604.             SndPlay(weaponSndChannel, (SndListHandle)killSomeBillSnd, true);
  605.             //wait for a while before moving on to level
  606.             Sleep(170);
  607.         }
  608.  
  609.     //hide cursor cause game is starting
  610.  
  611.     DrawGameBoard();
  612.     
  613.     if (prefs.sound)
  614.     {
  615.         SndPlay(otherSndChannel, (SndListHandle)zoomSnd, true);
  616.     }
  617.  
  618.     ZoomBlitWorkMapToScreen();
  619.     
  620.     
  621.     gWhere = kPlayingGame;
  622.     
  623. }
  624.  
  625. //////////////////////////////////////////////////////
  626. //Zoom to end level screen, draw all the stuff while
  627. //event response is locked, then go to StartLevel()
  628. //////////////////////////////////////////////////////
  629.  
  630. void EndLevel (void)
  631. {
  632.     short       i, state;
  633.     Rect        iconRect;
  634.     Str255      myString;
  635.     Rect        haukurPicRect = { 10, 300, 470, 623 };
  636.     CGrafPtr    frontBuffPort, backBuffPort;
  637.     
  638.     DSpContext_GetFrontBuffer(gDisplayContext, &frontBuffPort);
  639.     DSpContext_GetBackBuffer(gDisplayContext, kDSpBufferKind_Normal, &backBuffPort);
  640.     
  641.     SilenceAllChannels();
  642.  
  643.     gWhere = kEndLevel;
  644.     
  645.     if (currentLevel == kNumOfLevels-1)
  646.     {
  647.         GameWon();
  648.         return;
  649.         
  650.     }
  651.  
  652.     SetPort(backBuffPort);
  653.     //draw black workmap
  654.     DrawBlackWorkMap();
  655.     CopyBits((BitMap *)*haukurWinPix, GetPortBitMapForCopyBits(backBuffPort), &haukurWinSize, &haukurPicRect, srcCopy, nil);
  656.     
  657.     //play zoom sound
  658.     if (prefs.sound)
  659.     {
  660.         SndPlay(otherSndChannel, (SndListHandle)zoomSnd, true);
  661.     }
  662.             
  663.     ZoomBlitWorkMapToScreen();
  664.     
  665.     SetPort(frontBuffPort);
  666.             
  667.             RGBForeColor(&myWhiteColor);
  668.             
  669.             //Draw level X
  670.             MoveTo(190,130);
  671.             TextSize(12);
  672.             TextFace(1);
  673.             DrawString("¥pLevel ");
  674.             NumToString(currentLevel+1, myString);
  675.             DrawString(myString);
  676.             DrawString("¥p completed");
  677.             
  678.             RGBForeColor(&myBlackColor);
  679.             
  680.             if (prefs.sound)
  681.             {
  682.                 SndPlay(weaponSndChannel, (SndListHandle)bonkSnd, true);
  683.             }
  684.  
  685.             Sleep(30);
  686.  
  687.  
  688.             //Draw No. of Macs text
  689.             RGBForeColor(&myWhiteColor);
  690.             TextSize(10);
  691.             TextFace(1);
  692.             MoveTo(110,180);
  693.             DrawString("¥pMac Status  ");
  694.             
  695.             if (prefs.sound)
  696.             {
  697.                 SndPlay(weaponSndChannel, (SndListHandle)bonkSnd, true);
  698.             }
  699.             Sleep(20);
  700.             
  701.             //draw macs appearing
  702.             RGBForeColor(&myBlackColor);
  703.             
  704.             for (i = 0; i < levels[currentLevel].numOfMacs; i++)
  705.             {
  706.                 iconRect.top = 160;
  707.                 iconRect.left = 205 + (i * macIconSizes[0].right);
  708.                 iconRect.bottom = iconRect.top + macIconSizes[0].bottom;
  709.                 iconRect.right = iconRect.left + macIconSizes[0].right;
  710.                 
  711.                 //increment player stats for num of macs saved
  712.                 if (levels[currentLevel].macs[i].state == kMacOS)
  713.                     player.totalMacsSaved++;
  714.                 
  715.                 Sleep(9);
  716.                 
  717.                 RGBForeColor(&myBlackColor);
  718.                 state = levels[currentLevel].macs[i].state;
  719.                     if (state != kMacOS)
  720.                         state = kWinXP;
  721.                 CopyBits((BitMap *)*macIconPix, GetPortBitMapForCopyBits(frontBuffPort), &macIconSizes[state], &iconRect, srcCopy, nil);
  722.                 
  723.                 if (prefs.sound)
  724.                 {
  725.                     SilenceChannel(weaponSndChannel);
  726.                     SndPlay(weaponSndChannel, (SndListHandle)bonkSnd, true);
  727.                 }
  728.                 
  729.                 RGBForeColor(&myWhiteColor);
  730.                 MoveTo(iconRect.left, iconRect.bottom+15);
  731.                 
  732.                 if (levels[currentLevel].macs[i].state == kMacOS)
  733.                 {
  734.                     DrawString("¥p +");
  735.                     NumToString(kMacPointsGain, myString);
  736.                     DrawString(myString);
  737.                     player.score += 200;
  738.                     levelScore += 200;
  739.                 }
  740.                 else
  741.                 {
  742.                     DrawString("¥p -");
  743.                     NumToString(kMacPointsLose, myString);
  744.                     DrawString(myString);
  745.                     
  746.                     player.score -= 200;
  747.                     levelScore -= 200;
  748.                 }
  749.                 DrawString("¥p!");
  750.             }
  751.             
  752.             Sleep(30);
  753.             
  754.             TextFace(0);
  755.             
  756.             //draw Max no. of Bills text
  757.             RGBForeColor(&myWhiteColor);
  758.             MoveTo(120,230);
  759.             TextSize(10);
  760.             TextFace(1);
  761.             DrawString("¥p    Score");
  762.             
  763.             if (prefs.sound)
  764.             {
  765.                 SndPlay(weaponSndChannel, (SndListHandle)bonkSnd, true);
  766.             }
  767.             
  768.             RGBForeColor(&myBlackColor);
  769.             
  770.             Sleep(30);
  771.             
  772.             RGBForeColor(&myWhiteColor);
  773.             MoveTo(205,230);
  774.             NumToString(player.score, myString);
  775.             DrawString(myString);
  776.             
  777.             if (prefs.sound)
  778.             {
  779.                 SndPlay(weaponSndChannel, (SndListHandle)bonkSnd, true);
  780.             }
  781.             
  782.             RGBForeColor(&myBlackColor);
  783.  
  784.             Sleep(80);
  785.             
  786.             RGBForeColor(&myWhiteColor);
  787.             TextSize(12);
  788.             TextFace(1);
  789.             MoveTo(190,260);
  790.             DrawString("¥pGood Job, Soldier!");
  791.             
  792.             if (prefs.sound)
  793.             {
  794.                 SndPlay(weaponSndChannel, (SndListHandle)bonkSnd, true);
  795.             }
  796.             RGBForeColor(&myBlackColor);
  797.     
  798.     
  799.     
  800.     if (prefs.sound)
  801.     {
  802.         SndPlay(weaponSndChannel, (SndListHandle)goodJobSound, true);
  803.         Sleep(130);
  804.     }
  805.     
  806.     
  807.     UpOneLevel();
  808.     StartLevel(currentLevel);
  809.     
  810. }
  811.  
  812.  
  813. #pragma mark -
  814.  
  815. //////////////////////////////////////////////////////
  816. //Start responding to UI events again, paused
  817. //////////////////////////////////////////////////////
  818.  
  819.  
  820. void PauseGame (void)
  821. {
  822.     
  823.     //DSpContext_SetState(gDisplayContext, kDSpContextState_Paused);
  824.     
  825.     pauseTime = TickCount();
  826.     
  827.     if (gWhere == kGamePaused || gPlaying != true)
  828.         return;
  829.     
  830.     SetMenuStatus();
  831.     
  832.     SilenceAllChannels();
  833.     
  834.     gWhere = kGamePaused;
  835.  
  836.     ShowCursor();
  837.     
  838.     DrawPauseBarToWorkMap();
  839.     BlitWorkMapToScreen();
  840.     
  841.     if (prefs.sound)
  842.     {
  843.         SilenceChannel(otherSndChannel);
  844.         SndPlay(otherSndChannel, (SndListHandle)gamePausedSnd, true);
  845.     }
  846.     ShowMenuBar();
  847.     DrawMenuBar();
  848. }
  849.  
  850.  
  851. //////////////////////////////////////////////////////
  852. //Activate gameplay again
  853. //////////////////////////////////////////////////////
  854.  
  855. void EndPause (void)
  856. {
  857.     gWhere = kPlayingGame;
  858.     
  859.     HideCursor();
  860.     
  861.     BlitWorkMapToScreen();
  862. }
  863.  
  864.  
  865.  
  866. #pragma mark -
  867. //////////////////////////////////////////////////////
  868. //Well...checks if there are any remaining MacOS boxes
  869. //////////////////////////////////////////////////////
  870.  
  871. short CheckIfAllMacsHaveBecomeCorrupted (void)
  872. {
  873.     short i;
  874.     
  875.     for (i = 0; i < levels[currentLevel].numOfMacs; i++)
  876.     {
  877.         //if mac is running MacOS
  878.         if (levels[currentLevel].macs[i].state == kMacOS)
  879.         {
  880.             return(false);
  881.         }
  882.     }
  883.     
  884.     return true;
  885.     
  886.    
  887. }
  888.  
  889.  
  890. void ResetAllMacsInLevel (short levelNum)
  891. {
  892.     short i;
  893.     
  894.     //clean the last level
  895.     for (i = 0; i < levels[levelNum].numOfMacs; i++)
  896.     {
  897.         levels[levelNum].macs[i].state = kMacOS;
  898.     }
  899. }
  900.  
  901.  
  902. void ResetMacsInAllLevels (void)
  903. {
  904.     short i;
  905.     
  906.     for (i = 0; i < kNumOfLevels; i++)
  907.     {
  908.         ResetAllMacsInLevel(i);
  909.     }
  910.  
  911. }
  912.  
  913.  
  914. Rect *GetMacRect (short macNum)
  915. {
  916.     Rect    myMacRect;
  917.     short    type, state;
  918.     
  919.         type = levels[currentLevel].macs[macNum].type;
  920.         state = levels[currentLevel].macs[macNum].state;
  921.  
  922.         myMacRect.top = levels[currentLevel].macs[macNum].yloc;
  923.         myMacRect.left = levels[currentLevel].macs[macNum].xloc;
  924.         myMacRect.bottom = myMacRect.top + macRects[type][kMacOS].bottom;
  925.         myMacRect.right = myMacRect.left + (macRects[type][state].right-macRects[type][state].left);
  926.         
  927.       return(&myMacRect);
  928. }
  929.  
  930.  
  931.  
  932. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  933. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  934. //////////////////////////////Functions dealing with the Bill objects in level//////////////////////////////
  935. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  936. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  937.  
  938.  
  939. #pragma mark -
  940. #pragma mark ------  Bill  -------
  941.  
  942. void AddBill (void)
  943. {
  944.     short   rand;
  945.  
  946.     if (numOfBills < kMaxBills && billsInLevel < levels[currentLevel].numBills)
  947.     {
  948.         rand = RandomBetween(0,7);
  949.         
  950.             while (rand == lastBillStartLoc)
  951.             {
  952.                 rand = RandomBetween(0,7);
  953.             }
  954.         
  955.         lastBillStartLoc = rand;
  956.     
  957.         bills[numOfBills].xloc = billStartLocs[rand].h;
  958.         bills[numOfBills].yloc = billStartLocs[rand].v;
  959.         
  960.         bills[numOfBills].state = kBillWalkOne;
  961.         bills[numOfBills].countdown = 0;
  962.         
  963.         bills[numOfBills].points = kBillPoints;
  964.         bills[numOfBills].target = FindClosestBillTarget(numOfBills);
  965.         
  966.  
  967.         
  968.         numOfBills++;
  969.         billsInLevel++;
  970.  
  971.     }
  972.     
  973.     
  974.  
  975.  
  976.  
  977. }
  978.  
  979. void RemoveBill (short billNum)
  980. {
  981.     
  982.     //make the bill poof
  983.     if (bills[billNum].state == kBillHit || bills[billNum].state == kBillWinXP)
  984.     {
  985.         AddPoof(bills[billNum].xloc+4, bills[billNum].yloc+6, kPoofAway); 
  986.     }
  987.  
  988.     //remove bill in question from structure array
  989.     if (billNum == numOfBills-1)
  990.     {
  991.         numOfBills--;
  992.     }
  993.     else
  994.     {
  995.         while (billNum < numOfBills-1)
  996.         {
  997.             bills[billNum] = bills[billNum+1];
  998.             billNum++;
  999.         }
  1000.         numOfBills--;
  1001.     }
  1002.     
  1003.     
  1004.     //if there are no more bills and all the bills have appeared
  1005.     if (numOfBills == 0 && billsInLevel == levels[currentLevel].numBills)
  1006.     {
  1007.             levelCompleted = kLevelCompletedWaitPeriod;
  1008.     }
  1009.  
  1010. }
  1011.  
  1012.  
  1013.  
  1014.  
  1015.  
  1016. short FindClosestBillTarget (short billNum)
  1017. {
  1018.     short i;
  1019.     short distance = 0;
  1020.     short shortest = 15000;
  1021.     short shortestToMacNum = 0;
  1022.     
  1023.     for (i = 0; i < levels[currentLevel].numOfMacs; i++)
  1024.     {
  1025.         //if mac is running MacOS
  1026.         if (levels[currentLevel].macs[i].state == kMacOS)
  1027.         {
  1028.             //Pythagorean theorem a2+b2=c2
  1029.             //calculate how far it is
  1030.             distance = sqrt(         pow(bills[billNum].xloc - levels[currentLevel].macs[i].xloc, 2)
  1031.                                 + pow(bills[billNum].yloc - levels[currentLevel].macs[i].yloc, 2) 
  1032.                             );
  1033.        
  1034.             if (distance < shortest)
  1035.             {
  1036.                 shortest = distance;
  1037.                 shortestToMacNum = i;
  1038.             }
  1039.         }
  1040.     }
  1041.     
  1042.     if (shortest == 15000)
  1043.     {
  1044.         GameOver();
  1045.     }
  1046.     
  1047.     return(shortestToMacNum);
  1048. }
  1049.  
  1050.  
  1051. void DoBillMoves (void)
  1052. {
  1053.     short   i;
  1054.     float   perc;
  1055.     float   xdist,ydist;
  1056.     short   xmove,ymove;
  1057.     short   rand;
  1058.     
  1059.     for (i = 0; i < numOfBills; i++)
  1060.     {
  1061.     
  1062.             //ah...the bill isn't moving
  1063.             if (bills[i].countdown != 0)
  1064.             {
  1065.                 //if he's just been hit
  1066.                 if (bills[i].countdown == kBillHitDuration && bills[i].state == kBillHit)
  1067.                 {
  1068.                     if (prefs.sound)
  1069.                     {
  1070.                     SilenceChannel(billSndChannel);
  1071.                     SndPlay(billSndChannel, (SndListHandle)billScreamSnd, true);
  1072.                     }
  1073.                     
  1074.                 
  1075.                 }
  1076.                 
  1077.                 bills[i].countdown--;
  1078.                 
  1079.                 //if he's just waiting, painfully injured before disappearing
  1080.                 if (bills[i].state == kBillHit && bills[i].countdown == 0)
  1081.                 {
  1082.                     RemoveBill(i);
  1083.                     player.totalBillsKilled++;
  1084.                 }
  1085.                 
  1086.                 //if heォs loading WinXP on a Mac
  1087.                 else if (bills[i].state == kBillWinXP && bills[i].countdown == 0)
  1088.                 {
  1089.                 
  1090.                     
  1091.                     levels[currentLevel].macs[bills[i].target].state = kWinXP;
  1092.                     levels[currentLevel].macs[bills[i].target].countdown = kWinXPStateDuration + (RandomBetween(0,25));
  1093.                     
  1094.                     if (prefs.sound)
  1095.                     {
  1096.                         SilenceChannel(computerSndChannel);
  1097.                         SndPlay(computerSndChannel, (SndListHandle)winXPLoadedSnd, true);
  1098.                     }
  1099.                     RemoveBill(i);
  1100.  
  1101.                 }
  1102.                 
  1103.                 //if heォs indignant
  1104.                 else if (bills[i].state == kBillIndignant && bills[i].countdown == 0)
  1105.                 {
  1106.                     bills[i].state = kBillBriefcase;
  1107.                     bills[i].countdown = kBriefcaseWait;
  1108.                 }
  1109.                 //if heォs holding briefcase
  1110.                 else if (bills[i].state == kBillBriefcase && bills[i].countdown == 0)
  1111.                 {
  1112.                     bills[i].state = 0;
  1113.                 }
  1114.             }
  1115.             else
  1116.             {
  1117.                 //reduce the point value of the Bill if it's above minimum
  1118.                 if (bills[i].points > kMinBillPointValue)
  1119.                 {
  1120.                     bills[i].points -= kBillPointDecrease;
  1121.                 }
  1122.                 
  1123.                 if (levels[currentLevel].macs[bills[i].target].state == kWinXP)
  1124.                 {
  1125.                     bills[i].target = FindClosestBillTarget(i);
  1126.                     break;
  1127.                 }
  1128.                 
  1129.                 xdist = absolute(bills[i].xloc - levels[currentLevel].macs[bills[i].target].xloc);
  1130.                 ydist = absolute(bills[i].yloc - levels[currentLevel].macs[bills[i].target].yloc);
  1131.                 
  1132.                 if (xdist < currentBillSpeed && ydist < currentBillSpeed)
  1133.                 {
  1134.                     bills[i].xloc = levels[currentLevel].macs[bills[i].target].xloc;
  1135.                     bills[i].yloc = levels[currentLevel].macs[bills[i].target].yloc;
  1136.                 }
  1137.                 
  1138.                 
  1139.                 
  1140.                 //this is regular...we try to splitting the bill's move allotment equally between the two axises
  1141.                 if (currentBillSpeed != 1)
  1142.                 {
  1143.                     perc = (float)(xdist/(xdist+ydist));
  1144.                 
  1145.                     xmove = (perc*currentBillSpeed);
  1146.                     ymove = currentBillSpeed-xmove;
  1147.                 
  1148.                     if (bills[i].xloc > levels[currentLevel].macs[bills[i].target].xloc)
  1149.                     {
  1150.                         bills[i].xloc -= xmove;
  1151.                     }
  1152.                     else if (bills[i].xloc < levels[currentLevel].macs[bills[i].target].xloc)
  1153.                     {
  1154.                         bills[i].xloc += xmove;
  1155.                     }
  1156.                     
  1157.                     if (bills[i].yloc > levels[currentLevel].macs[bills[i].target].yloc)
  1158.                     {
  1159.                         bills[i].yloc -= ymove;
  1160.                     }
  1161.                     else if (bills[i].yloc < levels[currentLevel].macs[bills[i].target].yloc)
  1162.                     {
  1163.                         bills[i].yloc += ymove;
  1164.                     }
  1165.                 }
  1166.                 //we just do random whether he goes up or down
  1167.                 else if (currentBillSpeed == 1)
  1168.                 {
  1169.                     rand = RandomBetween(0,1);
  1170.                     
  1171.                     if (rand && bills[i].xloc != levels[currentLevel].macs[bills[i].target].xloc)
  1172.                     {
  1173.                         if (bills[i].xloc > levels[currentLevel].macs[bills[i].target].xloc)
  1174.                         {
  1175.                             bills[i].xloc -= 1;
  1176.                         }
  1177.                         else if (bills[i].xloc < levels[currentLevel].macs[bills[i].target].xloc)
  1178.                         {
  1179.                             bills[i].xloc += 1;
  1180.                         }
  1181.                     }
  1182.                     else
  1183.                     {
  1184.                         if (bills[i].yloc > levels[currentLevel].macs[bills[i].target].yloc)
  1185.                         {
  1186.                             bills[i].yloc -= 1;
  1187.                         }
  1188.                         else if (bills[i].yloc < levels[currentLevel].macs[bills[i].target].yloc)
  1189.                         {
  1190.                             bills[i].yloc += 1;
  1191.                         }
  1192.                     }
  1193.                 
  1194.                 }
  1195.                 
  1196.                 
  1197.                 if (bills[i].yloc == levels[currentLevel].macs[bills[i].target].yloc &&
  1198.                     bills[i].xloc == levels[currentLevel].macs[bills[i].target].xloc )
  1199.                     {
  1200.                         bills[i].state = kBillWinXP;
  1201.                         
  1202.                         bills[i].countdown = 10;
  1203.                     }
  1204.                     else
  1205.                     {
  1206.                         //shift between the two pics to make an animation
  1207.                         bills[i].state = !bills[i].state;
  1208.                     }
  1209.             }
  1210.     
  1211.     
  1212.     }
  1213.     
  1214. }
  1215.  
  1216. Rect* GetBillRect (short billNum)
  1217. {
  1218.     Rect theBillRect;
  1219.     
  1220.     theBillRect.top = bills[billNum].yloc;
  1221.     theBillRect.left = bills[billNum].xloc;
  1222.     theBillRect.bottom = bills[billNum].yloc+kBillHeight;
  1223.     theBillRect.right = bills[billNum].xloc+kBillWidth;
  1224.     
  1225.     return(&theBillRect);
  1226. }
  1227.  
  1228.  
  1229.  
  1230.  
  1231. #pragma mark -
  1232. #pragma mark -----  Steve  -----
  1233. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1234. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1235. //////Functions dealing with THE MAN himself and his interaction with the world of Billslaughtering/////////
  1236. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1237. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1238.  
  1239. void AddSteve (void)
  1240. {
  1241.     short rand, i;
  1242.     short isThereAnInfectedMac = false;
  1243.     
  1244.     for (i = 0; i < levels[currentLevel].numOfMacs; i++)
  1245.     {
  1246.         //if mac is running windows
  1247.         if (levels[currentLevel].macs[i].state == kWinXP)
  1248.         {
  1249.             isThereAnInfectedMac = true;
  1250.         }
  1251.       }
  1252.     
  1253.     if (!numOfSteves && isThereAnInfectedMac == true)//there can be only ONE!
  1254.     {
  1255.         rand = RandomBetween(0,7);
  1256.      
  1257.         steve.xloc = billStartLocs[rand].h;
  1258.         steve.yloc = billStartLocs[rand].v;
  1259.         
  1260.         steve.state = kBillWalkOne;
  1261.         steve.countdown = 0;
  1262.         
  1263.         steve.target = FindClosestSteveTarget();
  1264.         
  1265.         numOfSteves = true;
  1266.       }
  1267. }
  1268.  
  1269. void RemoveSteve (void)
  1270. {
  1271.     AddPoof(steve.xloc+4, steve.yloc+6, kPoofAway);
  1272.  
  1273.     numOfSteves = 0;
  1274. }
  1275.  
  1276.  
  1277.  
  1278.  
  1279. short FindClosestSteveTarget (void)
  1280. {
  1281.     short i;
  1282.     short distance = 0;
  1283.     short shortest = 15000;
  1284.     short shortestToWinNum = 15000;
  1285.     
  1286.     for (i = 0; i < levels[currentLevel].numOfMacs; i++)
  1287.     {
  1288.         //if mac is running MacOS
  1289.         if (levels[currentLevel].macs[i].state != kMacOS)
  1290.         {
  1291.             //Pythagorean theorem a2+b2=c2
  1292.             //calculate how far it is
  1293.             distance = sqrt(         pow(steve.xloc - levels[currentLevel].macs[i].xloc, 2)
  1294.                                 + pow(steve.yloc - levels[currentLevel].macs[i].yloc, 2) 
  1295.                             );
  1296.        
  1297.             if (distance < shortest)
  1298.             {
  1299.                 shortest = distance;
  1300.                 shortestToWinNum = i;
  1301.             }
  1302.         }
  1303.     }
  1304.     
  1305.     return(shortestToWinNum);
  1306.  
  1307. }
  1308.  
  1309.  
  1310.  
  1311. void DoSteveMove (void)
  1312. {
  1313.     short   i = 0;
  1314.     float   perc;
  1315.     float   xdist,ydist;
  1316.     short   xmove,ymove;
  1317.     short   targetX, targetY;
  1318.     
  1319.     if (numOfSteves)
  1320.     {
  1321.         //if the steve isn't moving
  1322.         if (steve.countdown != 0)
  1323.         {
  1324.             //if he's just been hit
  1325.             if (steve.countdown == kBillHitDuration && steve.state == kBillHit)
  1326.             {
  1327.                 if (prefs.sound)
  1328.                 {
  1329.                     SilenceChannel(steveSndChannel);
  1330.                       SndPlay(steveSndChannel, (SndListHandle)steveScreamSnd, true);
  1331.                 }
  1332.             }
  1333.             steve.countdown--;
  1334.             
  1335.             
  1336.             //if he's just waiting, painfully injured before disappearing
  1337.             if (steve.state == kBillHit && steve.countdown == 0)
  1338.             {
  1339.                 RemoveSteve();
  1340.             }
  1341.             //if heォs loading MacOS on a WinXP Mac
  1342.             else if (steve.state == kBillWinXP && steve.countdown == 0)
  1343.             {
  1344.                 if (prefs.sound)
  1345.                 {
  1346.                     SilenceChannel(computerSndChannel);
  1347.                     SndPlay(computerSndChannel, (SndListHandle)macOSLoadedSnd, true);
  1348.                 }
  1349.                 levels[currentLevel].macs[steve.target].state = kMacOS;
  1350.                 steve.state = 0;
  1351.             }
  1352.         }
  1353.         else
  1354.         {
  1355.             
  1356.             if (levels[currentLevel].macs[steve.target].state == kMacOS)
  1357.             {
  1358.                 steve.target = FindClosestSteveTarget();
  1359.                 if (steve.target == 15000)
  1360.                     RemoveSteve();
  1361.             }
  1362.             
  1363.                 targetX = levels[currentLevel].macs[steve.target].xloc;
  1364.                 targetY = levels[currentLevel].macs[steve.target].yloc;
  1365.             
  1366.             xdist = absolute(steve.xloc - targetX);
  1367.             ydist = absolute(steve.yloc - targetY);
  1368.             
  1369.             if (xdist < kSteveSpeed && ydist < kSteveSpeed)
  1370.             {
  1371.                 steve.xloc = targetX;
  1372.                 steve.yloc = targetY;
  1373.             }
  1374.             
  1375.             perc = (float)(xdist/(xdist+ydist));
  1376.             
  1377.             xmove = (perc*kSteveSpeed);
  1378.             ymove = kSteveSpeed-xmove;
  1379.             
  1380.             
  1381.             
  1382.         if (steve.xloc > targetX)
  1383.         {
  1384.             steve.xloc -= xmove;
  1385.         }
  1386.         else if (steve.xloc < targetX)
  1387.         {
  1388.             steve.xloc += xmove;
  1389.         }
  1390.         
  1391.         if (steve.yloc > targetY)
  1392.         {
  1393.             steve.yloc -= ymove;
  1394.         }
  1395.         else if (steve.yloc < targetY)
  1396.         {
  1397.             steve.yloc += ymove;
  1398.         }
  1399.         
  1400.         
  1401.         //if steve has arrived at his target
  1402.         if (steve.yloc == targetY &&
  1403.             steve.xloc == targetX )
  1404.             {
  1405.                     steve.state = kBillWinXP;
  1406.                     steve.countdown = 10;
  1407.             }
  1408.             else
  1409.             {
  1410.                 //shift between the two pics to make an animation
  1411.                 steve.state = !steve.state;
  1412.             }
  1413.        }
  1414.  
  1415.     }
  1416. }
  1417.  
  1418.  
  1419.  
  1420.  
  1421.  
  1422. Rect* GetSteveRect (void)
  1423. {
  1424.     Rect    steveRect;
  1425.     
  1426.     steveRect.top = steve.yloc;
  1427.     steveRect.left = steve.xloc;
  1428.     steveRect.bottom = steve.yloc+kBillHeight;
  1429.     steveRect.right = steve.xloc+kBillWidth;
  1430.     
  1431.     return(&steveRect);
  1432. }
  1433.  
  1434.  
  1435. #pragma mark -
  1436. #pragma mark ------- DOJs -----
  1437. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1438. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1439. /////////////////////////////////// The Department of Justice Effects///////////////////////////////////////
  1440. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1441. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1442.  
  1443. void AddDoj (void)
  1444. {
  1445.     Rect        dojRect, macRect, someRect;
  1446.     short       i, doesItSect = false, type, state, validDojLoc = false;
  1447.     
  1448.     if (numOfDojs > 1)
  1449.         return;
  1450.     
  1451.     while (!validDojLoc)
  1452.     {
  1453.         doesItSect = false;
  1454.     
  1455.         dojRect.top = RandomBetween(10, 400);
  1456.         dojRect.left = RandomBetween(10, 580);
  1457.         dojRect.bottom = dojRect.top+dojSize.bottom;
  1458.         dojRect.right = dojRect.left+dojSize.right;
  1459.         
  1460.         
  1461.         
  1462.         //does the doj rect overlap a mac in the level?
  1463.         for (i = 0; i < levels[currentLevel].numOfMacs; i++)
  1464.         {
  1465.            type = levels[currentLevel].macs[i].type;
  1466.             state = levels[currentLevel].macs[i].state;
  1467.         
  1468.             macRect.top = levels[currentLevel].macs[i].yloc;
  1469.             macRect.left = levels[currentLevel].macs[i].xloc;
  1470.             macRect.bottom = macRect.top + macRects[type][kMacOS].bottom;
  1471.             macRect.right = macRect.left + (macRects[type][state].right-macRects[type][state].left);
  1472.             
  1473.             if (SectRect(&macRect, &dojRect, &someRect))
  1474.             {
  1475.                 doesItSect = true;
  1476.             }
  1477.         }
  1478.         
  1479.         //does it overlap another doj?
  1480.         for (i = 0; i < numOfDojs; i++)
  1481.         {
  1482.             
  1483.             if (SectRect(&dojs[i].rect, &dojRect, &someRect))
  1484.             {
  1485.                 doesItSect = true;
  1486.             }
  1487.         }
  1488.         
  1489.         //if not, it's good
  1490.         if (!doesItSect)
  1491.                 validDojLoc = true;
  1492.         
  1493.     }
  1494.     
  1495.     dojs[numOfDojs].rect = dojRect;
  1496.     dojs[numOfDojs].countdown = kDojDuration;
  1497.     
  1498.     
  1499.     numOfDojs++;
  1500.     
  1501.     if (prefs.sound)
  1502.     {
  1503.         SndPlay(dojSndChannel, (SndListHandle)dojAppearsSnd, true);
  1504.     }
  1505.     
  1506. }
  1507.  
  1508. void RemoveDoj (short dojNum)
  1509. {
  1510.  
  1511.     if (dojNum == 1)
  1512.     {
  1513.         numOfDojs--;
  1514.     }
  1515.     else if (dojNum == 0)
  1516.     {
  1517.         dojs[0] = dojs[1];
  1518.         numOfDojs--;
  1519.     }
  1520. }
  1521.  
  1522.  
  1523. void DepartmentOfJusticeEffect (void)
  1524. {
  1525.     short i;
  1526.     
  1527.     if (player.dojs == 0)
  1528.     {
  1529.         //The Republicans are in power this time, it seems
  1530.         return;
  1531.     }
  1532.     else if (dojCooldown == 0)
  1533.     {
  1534.         player.dojs--;
  1535.     
  1536.         for (i = 0; i < numOfBills; i++)
  1537.         {
  1538.             if (bills[i].state != kBillHit)
  1539.             {
  1540.                 bills[i].state = kBillIndignant;
  1541.                 bills[i].countdown = kIndignantWait;
  1542.             }
  1543.             
  1544.         }
  1545.         
  1546.         if (prefs.sound)
  1547.         {
  1548.             SilenceChannel(dojSndChannel);
  1549.             //let's hear bill refuting the charges
  1550.             if (numOfBills)
  1551.             {
  1552.                 SndPlay(dojSndChannel, (SndListHandle)billIndignantSnd, true);
  1553.             }
  1554.         }
  1555.         
  1556.         dojCooldown = kDoJCoolDown;
  1557.     }
  1558. }
  1559.  
  1560.  
  1561.  
  1562. #pragma mark -
  1563. #pragma mark -------- Poofs ---------
  1564. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1565. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1566. //////////////////////////////////////////// The Poofs//////////////////////////////////////////////////////
  1567. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1568. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  1569.  
  1570. void AddPoof (short x, short y, short effectType)
  1571. {
  1572.     if (numOfPoofs < kMaxPoofLimit)
  1573.     {
  1574.         poofs[numOfPoofs].xloc = x;
  1575.         poofs[numOfPoofs].yloc = y;
  1576.         poofs[numOfPoofs].effect = effectType;
  1577.         poofs[numOfPoofs].state = 0;
  1578.     
  1579.         numOfPoofs++;
  1580.     }
  1581.     else
  1582.     {
  1583.         RemovePoof(0);
  1584.         AddPoof(x,y, effectType);
  1585.     }
  1586.     
  1587. }
  1588.  
  1589.  
  1590. void RemovePoof (short poofNum)
  1591. {
  1592.  
  1593.     if (poofNum == numOfPoofs-1)
  1594.     {
  1595.         numOfPoofs--;
  1596.     }
  1597.     else
  1598.     {
  1599.         while (poofNum < numOfPoofs-1)
  1600.         {
  1601.             poofs[poofNum] = poofs[poofNum+1];
  1602.             poofNum++;
  1603.         }
  1604.         numOfPoofs--;
  1605.     }
  1606.     if (prefs.sound)
  1607.     {
  1608.         SilenceChannel(otherSndChannel);
  1609.         SndPlay(otherSndChannel, (SndListHandle)poofSnd, true);
  1610.     }
  1611.             
  1612.     
  1613. }
  1614.  
  1615.  
  1616. void DoExtraMoves (void)
  1617. {
  1618.     short i, state, type, countdown;
  1619.  
  1620.     //DoJs
  1621.     if (numOfDojs)
  1622.     {
  1623.         for (i = 0; i < numOfDojs; i++)
  1624.         {
  1625.         
  1626.             if (dojs[i].countdown != 0)
  1627.             {
  1628.                 dojs[i].countdown--;
  1629.             }
  1630.             else
  1631.             {
  1632.                 RemoveDoj(i);
  1633.             }
  1634.             
  1635.         }
  1636.     
  1637.     }
  1638.     
  1639.     //poofs
  1640.     if (numOfPoofs)
  1641.     {
  1642.         for (i = 0; i < numOfPoofs; i++)
  1643.         {
  1644.             
  1645.             if (poofs[i].state == 4)
  1646.             {
  1647.                 RemovePoof(i);
  1648.             }
  1649.             poofs[i].state++;
  1650.         }
  1651.     }
  1652.     
  1653.     //Macs
  1654.     for (i = 0; i < levels[currentLevel].numOfMacs; i++)
  1655.     {
  1656.         state = levels[currentLevel].macs[i].state;
  1657.         type = levels[currentLevel].macs[i].type;
  1658.         countdown = levels[currentLevel].macs[i].countdown;
  1659.         
  1660.         if (state == kMacOS)
  1661.         {
  1662.         }
  1663.         else if (state == kWinXP && countdown != 0)
  1664.         {
  1665.             levels[currentLevel].macs[i].countdown--;
  1666.         }
  1667.         else if (state == kWinXP && countdown == 0 )
  1668.         {
  1669.             
  1670.             levels[currentLevel].macs[i].state = kWinCrash;
  1671.             levels[currentLevel].macs[i].countdown = (macScreenRects[type].bottom - macScreenRects[type].top)/2;
  1672.             
  1673.             if (prefs.sound)
  1674.             {
  1675.                 SilenceChannel(computerSndChannel);
  1676.                 SndPlay(computerSndChannel, (SndListHandle)beepSnd, true);
  1677.             }
  1678.         }
  1679.         else if (state == kWinCrash && countdown == -1)
  1680.         {
  1681.             levels[currentLevel].macs[i].state = kWinCrashErr;
  1682.             levels[currentLevel].macs[i].countdown = kErrorFlashPause;
  1683.         }
  1684.         else if (state == kWinCrash && countdown < -1)
  1685.         {
  1686.            levels[currentLevel].macs[i].countdown++; 
  1687.         }
  1688.         else if (state == kWinCrash && countdown != 0)
  1689.         { 
  1690.             levels[currentLevel].macs[i].countdown--;
  1691.         }
  1692.         else if (state == kWinCrash && countdown == 0)
  1693.         {
  1694.             levels[currentLevel].macs[i].state = kWinCrashErr;
  1695.             levels[currentLevel].macs[i].countdown = kErrorFlashPause;
  1696.         }
  1697.         else if (state == kWinCrashErr && countdown == 0)
  1698.         {
  1699.             if(RandomBetween(0, kChanceOfReboot) == 1)
  1700.             {
  1701.                 levels[currentLevel].macs[i].state = kWinXP;
  1702.                 levels[currentLevel].macs[i].countdown = kWinXPStateDuration + (RandomBetween(0, 25));
  1703.             }
  1704.             else
  1705.             {
  1706.                 levels[currentLevel].macs[i].state = kWinCrash;
  1707.                 levels[currentLevel].macs[i].countdown = -kErrorFlashPause;
  1708.             }
  1709.             
  1710.         }
  1711.         else if (state == kWinCrashErr && countdown > 0)
  1712.         {
  1713.             levels[currentLevel].macs[i].countdown--;
  1714.         }
  1715.     }
  1716.  
  1717.  
  1718. }
  1719.  
  1720.  
  1721. #pragma mark -
  1722.  
  1723.  
  1724. //////////////////////////////////////////////////////
  1725. //Check whether player gets a goodie.  If all macs are
  1726. //clean he gets a DoJ, otherwise he gets THE MAN himself.
  1727. //////////////////////////////////////////////////////
  1728.  
  1729. void RandomGoodie (short chance)
  1730. {
  1731.     short rand, i;
  1732.     short isThereAnInfectedMac = false;
  1733.     
  1734.     rand = RandomBetween(1, chance);
  1735.  
  1736.     if (rand == chance)
  1737.     {
  1738.         
  1739.     for (i = 0; i < levels[currentLevel].numOfMacs; i++)
  1740.         {
  1741.             //if mac is running windows
  1742.             if (levels[currentLevel].macs[i].state == kWinXP)
  1743.             {
  1744.             isThereAnInfectedMac = true;
  1745.             }
  1746.       }
  1747.         
  1748.         if (isThereAnInfectedMac)
  1749.             AddSteve();
  1750.         else
  1751.             AddDoj();
  1752.     }
  1753. }
  1754.  
  1755.  
  1756. #pragma mark -
  1757.  
  1758. //////////////  CHECK KEY INPUT DURING GAME  ///////////////
  1759.  
  1760. void CheckKeysInGame (void)
  1761. {
  1762.     KeyMap    myKeyMap;
  1763.  
  1764.     GetKeys(myKeyMap);
  1765.  
  1766.     //we pause on space bar or P
  1767.     if(CheckKeyMapForKey(myKeyMap, 35/*P*/) || CheckKeyMapForKey(myKeyMap, 49/*spacebar*/))
  1768.     {
  1769.         PauseGame();
  1770.     }
  1771.     //end game on Q
  1772.     else if(CheckKeyMapForKey(myKeyMap, 12/*Q*/))
  1773.     {
  1774.         GameOver();
  1775.     }
  1776.     //cheat and add DoJ on C
  1777.     else if(CheckKeyMapForKey(myKeyMap, 8/*C*/))
  1778.     {
  1779.         AddDoj();
  1780.         cheated = true;
  1781.     }
  1782.     //Option uses a DoJ
  1783.     else if (CheckKeyMapForKey(myKeyMap, 58))//option button
  1784.     {
  1785.        DepartmentOfJusticeEffect();
  1786.     }
  1787.  
  1788. }
  1789.  
  1790.  
  1791.  
  1792. //////////////////////////////////////////////////////
  1793. //Check where mouse is, and what the user is doing with it.
  1794. //Handles ingame mouse interaction with game objects
  1795. //////////////////////////////////////////////////////
  1796.  
  1797. void CheckForMouse (void)
  1798. {
  1799.     Rect    theRect;
  1800.     Point   clickLoc;
  1801.     short i, buttonDown;
  1802.     
  1803.     buttonDown = Button();
  1804.     
  1805.     //make the chainsaw rotate if mousebutton is down
  1806.     if (buttonDown && !mouseJammed)
  1807.             weaponState = !weaponState;
  1808.     
  1809.     GetMouse(&clickLoc);
  1810.     
  1811.     if (clickLoc.h < 0)
  1812.         clickLoc.h = 0;
  1813.        if (clickLoc.v < 0)
  1814.            clickLoc.v = 0;
  1815.        if (clickLoc.h > 640-32)
  1816.            clickLoc.h = 640-32;
  1817.        if (clickLoc.v > 460-32)
  1818.            clickLoc.v = 460-32;
  1819.     
  1820.     //get the 32x32 chainsaw pic rect
  1821.     theRect.top = clickLoc.v;
  1822.     theRect.left = clickLoc.h;
  1823.     theRect.bottom = clickLoc.v+chainsawSizes[0].bottom;
  1824.     theRect.right = clickLoc.h+chainsawSizes[0].right;
  1825.  
  1826.     GetMouse(&clickLoc);
  1827.     
  1828.     //if chainsaw is jammed, it can't hurt the Bills
  1829.     if (mouseJammed)
  1830.     {
  1831.         if (buttonDown)
  1832.         {
  1833.             //Play horrible grinding sound as chainsaw throttles
  1834.         }
  1835.         
  1836.         mouseCountdown--;
  1837.         
  1838.         if (mouseCountdown == 0)
  1839.         {
  1840.             mouseJammed = false;
  1841.         }
  1842.         
  1843.         return;
  1844.     }
  1845.  
  1846.     if (buttonDown)
  1847.     {
  1848.         mouseDownLast = true;
  1849.         
  1850.         mouseCount++;
  1851.         
  1852.         if (prefs.sound)
  1853.         {
  1854.             //play weapon sound
  1855.             SndPlay(weaponSndChannel, (SndListHandle)chainsawSnd, true);
  1856.         }
  1857.     }
  1858.     else
  1859.     {
  1860.         SilenceChannel(weaponSndChannel);
  1861.         mouseDownLast = false;
  1862.         mouseCount =0;
  1863.     }
  1864.     
  1865.     
  1866.     if (mouseCount == kChainsawJamTime && !prefs.noChainsawJamming)
  1867.     {
  1868.         mouseJammed = true;
  1869.         mouseCountdown = kChainsawJammedWait;
  1870.         
  1871.         if (prefs.sound)
  1872.         {
  1873.             SilenceChannel(weaponSndChannel);
  1874.             SndPlay(weaponSndChannel, (SndListHandle)jammedSnd, true);
  1875.         }
  1876.     }
  1877.  
  1878.     
  1879.     //if there are bills on the board
  1880.     if (numOfBills)
  1881.     {
  1882.         for (i = 0; i < numOfBills; i++)
  1883.         {
  1884.             theRect.top = bills[i].yloc;
  1885.             theRect.left = bills[i].xloc;
  1886.             theRect.bottom = bills[i].yloc+64;
  1887.             theRect.right = bills[i].xloc+50;
  1888.             
  1889.             if(PtInRect(clickLoc, &theRect) && buttonDown && bills[i].state != kBillWinXP)
  1890.             {
  1891.                 //if he's already hit we can keep him suffering
  1892.                 if (bills[i].state == kBillHit)
  1893.                 {
  1894.                   //  bills[i].countdown = 15;
  1895.                 }
  1896.                 else
  1897.                 {
  1898.                     //let the bill know heォs dead
  1899.                     bills[i].state = kBillHit;
  1900.                     bills[i].countdown = kBillHitDuration;
  1901.  
  1902.                     player.score += bills[i].points;
  1903.                     levelScore += bills[i].points;
  1904.                     
  1905.                 }
  1906.                             
  1907.                 return;
  1908.             }
  1909.         }
  1910.     }
  1911.     
  1912.     //if there's a Steve in action, we need to check if the player hit him
  1913.     if (numOfSteves)
  1914.     {
  1915.         theRect.top = steve.yloc;
  1916.         theRect.left = steve.xloc;
  1917.         theRect.bottom = steve.yloc+64;
  1918.         theRect.right = steve.xloc+50;
  1919.         
  1920.         if (PtInRect(clickLoc, &theRect) && buttonDown && steve.state != kBillWinXP)
  1921.         {
  1922.             if (steve.state == kBillHit)
  1923.             {
  1924.             
  1925.             }
  1926.             else
  1927.             {
  1928.                 //AAAAAAAAAARGH!! This damn player has killed THE MAN himself
  1929.                 //time to bring out the artilley
  1930.                 player.score -= kSteveKillPenalty;
  1931.                 if (player.score < 0)
  1932.                     player.score = 0;
  1933.                 steve.state = kBillHit;
  1934.                 steve.countdown = 15;
  1935.             }
  1936.             
  1937.             return;
  1938.         }
  1939.     }
  1940.     
  1941.     //if there's a DoJ on the board, check if player got it
  1942.     if (numOfDojs)
  1943.     {
  1944.         for (i = 0; i < numOfDojs; i++)
  1945.         {
  1946.             if (PtInRect(clickLoc, &dojs[i].rect) && buttonDown)
  1947.             {
  1948.                 if (prefs.sound)
  1949.                 {
  1950.                     SilenceChannel(dojSndChannel);
  1951.                     SndPlay(dojSndChannel, (SndListHandle)dojCaughtSnd, true);
  1952.                 }
  1953.                 
  1954.                 RemoveDoj(i);
  1955.                 player.dojs++;
  1956.                 
  1957.                 return;
  1958.             }
  1959.         }
  1960.     }
  1961.     
  1962.     
  1963.     
  1964. }
  1965.  
  1966.